home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Tool Chest / Testing & Debugging / Virtual User / Virtual User Current Release / Examples / Example External Tools / ProcessTool / AERequest.cp next >
Encoding:
Text File  |  1998-06-04  |  24.3 KB  |  983 lines  |  [TEXT/MPS ]

  1. /*
  2.  *    File:        AERequest.cp
  3.  *
  4.  *    Contains:    xxx put contents here xxx
  5.  *
  6.  *    Written by:    Rick Violet
  7.  *
  8.  *    Copyright:    © 1992-1994 by Apple Computer, Inc., all rights reserved.
  9.  *
  10.  *    Change History (most recent first):
  11.  *
  12.  *         <4>     1/27/94    BD        Relstring moved to TextUtils.h from Packages.h.
  13.  *        <3+>     1/27/94    BD        Relstring moved to TextUtils.h from Packages.h.
  14.  *         <3>     1/27/94    BD        Update for MPW 3.3, include TextUtils.h
  15.  *        <2+>     1/27/94    BD        Update for MPW 3.3, include TextUtils.h
  16.  *        <1+>     1/13/94    CMW        Update for new external tool protocol (AppleScriptable).
  17.  *        <1+>     5/18/93    RV        Now accepts parameters of type 'true', 'fals', and 'BOOL' from
  18.  *                                    the Apple Events
  19.  *        <7+>    11/19/92    RV        
  20.  *                11/18/92    RV        xxx put comment here xxx
  21.  *
  22.  *    To Do:
  23.  */
  24.  
  25. #ifndef        __AERequest__
  26. #include        "AERequest.h"
  27. #endif
  28.  
  29. #ifndef        __RequestDispatcher__
  30. #include        "RequestDispatcher.h"
  31. #endif
  32.  
  33. #ifndef        __ERRORS__
  34. #include        <Errors.h>
  35. #endif
  36.  
  37. #ifndef        __TEXTUTILS__
  38. #include        <TextUtils.h>
  39. #endif
  40.  
  41. //—————————————————————————————————————————————————————————————————————————————————————
  42. //                                Global Variables
  43. //—————————————————————————————————————————————————————————————————————————————————————
  44. extern    RequestDispatcher*        gTheRequestDispatcher;
  45.  
  46. //—————————————————————————————————————————————————————————————————————————————————————
  47. //    AERequestHandler - handles 'v.u.' 'extc' apple event
  48. //—————————————————————————————————————————————————————————————————————————————————————
  49. pascal    OSErr  
  50. AERequestHandler( AppleEvent* pMessage, AppleEvent* pReply, long )
  51. {
  52.     OSErr                tErr;
  53.     AERequest*            tSrvReq;
  54.  
  55.         //————    Construct AERequest and put it in the request queue
  56.     tSrvReq = new AERequest( pMessage, pReply );
  57.     if( tSrvReq != nil )
  58.     {
  59.         tErr = tSrvReq->Initialize();
  60.         if( tErr )
  61.         {
  62.             delete tSrvReq;
  63.         }
  64.         else
  65.         {
  66.             gTheRequestDispatcher->QueueRequest( tSrvReq );
  67.         }
  68.     }
  69.  
  70.     return( tErr );
  71. }
  72.  
  73. //—————————————————————————————————————————————————————————————————————————————————————
  74. //    AERequest::AERequest    -    constructor.
  75. //—————————————————————————————————————————————————————————————————————————————————————
  76. AERequest::AERequest( AppleEvent* pMessage, AppleEvent* pReply )
  77. {
  78.     fMessagePtr         = pMessage;
  79.     fReplyPtr           = pReply;    
  80.     fSuspended             = false;
  81.     fReturnID             = 0;
  82.     fHaveResetTimerMsg    = false;
  83. }
  84.  
  85. //—————————————————————————————————————————————————————————————————————————————————————
  86. //    AERequest::~AERequest    -    destructor.
  87. //—————————————————————————————————————————————————————————————————————————————————————
  88. AERequest::~AERequest()
  89. {
  90.  
  91.         //————    Only if we successfully suspended the AppleEvent 
  92.         //————    are we responcible for disposing of the AppleEvent descriptors;
  93.         //————    because the AppleEvent Manager will automatically 
  94.         //————    dispose of them when we return from the Handler.
  95.     if( fSuspended )
  96.     {
  97.         AEDisposeDesc( fMessagePtr );
  98.         AEDisposeDesc( fReplyPtr );
  99.     }
  100.     
  101.         //————    if we created a TimeOut Reset AppleEvent, then dispose of it
  102.     if( fHaveResetTimerMsg )
  103.     {
  104.         AEDisposeDesc( &fResetTimerMsg );
  105.     }
  106. }
  107.  
  108. //—————————————————————————————————————————————————————————————————————————————————————
  109. //    AERequest::GetIdentifierOfRequesttoCancel    -    return the request
  110. //        identifier of the request to cancel. 
  111. //        This method is for use with cancel requests only.
  112. //—————————————————————————————————————————————————————————————————————————————————————
  113. long
  114. AERequest::GetIdentifierOfRequesttoCancel()
  115. {
  116.     ScriptValue*    tVal;
  117.     ValueKind        tVKind = kVUAnyKind;
  118.     long            tResult = 0;
  119.     
  120.     GetNthParam( 1, tVal, tVKind );
  121.     if( tVal )
  122.     {
  123.         switch( tVKind )
  124.         {
  125.             case kVULongNumberKind:
  126.             {
  127.                 tResult = ((VULongNumber*)tVal)->GetNumber();
  128.             }
  129.             break;
  130.             
  131.             case kVUStringKind:
  132.             {
  133.                 stringtonum( ((VUString*)tVal)->GetText(), &tResult );
  134.             }
  135.             break;
  136.         }
  137.     }
  138.     
  139.     return tResult;
  140. }
  141.  
  142. //—————————————————————————————————————————————————————————————————————————————————————
  143. //    AERequest::InstallAppleEventHandler    - Install an AppleEvent Handler
  144. //                                                into the AE dispatch table for receiving 
  145. //                                                Apple Events from V.U.
  146. //—————————————————————————————————————————————————————————————————————————————————————
  147. OSErr
  148. AERequest::InstallAppleEventHandler()
  149. {    
  150.     return AEInstallEventHandler(    kVUAETool,
  151.                                       kVUAESendService,
  152.                                     (EventHandlerProcPtr)AERequestHandler,
  153.                                        0, false);
  154.  
  155. }
  156.  
  157. //—————————————————————————————————————————————————————————————————————————————————————
  158. //    AERequest::SetErrorCode    - set the Error code for this request
  159. //—————————————————————————————————————————————————————————————————————————————————————
  160. void
  161. AERequest::SetErrorCode( OSErr tErr )
  162. {
  163.     if( fReplyPtr != nil )
  164.     {
  165.         AEPutAttributePtr(    fReplyPtr,
  166.                             keyErrorNumber,
  167.                             typeShortInteger,
  168.                             (Ptr)&tErr,
  169.                             sizeof( OSErr ) );
  170.     }
  171.     
  172.     Request::SetErrorCode( tErr );
  173. }
  174.  
  175. //—————————————————————————————————————————————————————————————————————————————————————
  176. //    AERequest::SetErrorMessage    - set the Error message for this request
  177. //—————————————————————————————————————————————————————————————————————————————————————
  178. void
  179. AERequest::SetErrorMessage( char* tErrText )
  180. {
  181.     if( fReplyPtr != nil )
  182.     {
  183.         AEPutAttributePtr(    fReplyPtr,
  184.                             keyErrorString,
  185.                             typeChar,
  186.                             (Ptr)tErrText,
  187.                             strlen( tErrText ) );
  188.     }
  189.     
  190.     Request::SetErrorMessage( tErrText );
  191. }
  192.  
  193. //—————————————————————————————————————————————————————————————————————————————————————
  194. //    AERequest::Initialize    -    initialize the Request
  195. //                                        Transfers info in AppleEvents to the
  196. //                                        Request object
  197. //—————————————————————————————————————————————————————————————————————————————————————
  198. OSErr
  199. AERequest::Initialize()
  200. {
  201.     OSErr    tErr = noErr;
  202.  
  203.         //————    Suspend processing of the AppleEvent by the AE Manager
  204.         //————    This prevents the reply AppleEvent from being sent back 
  205.         //————    when this routine returns ( actually it's when the AE Handler returns ).
  206.     tErr = AESuspendTheCurrentEvent( fMessagePtr );
  207.     if( tErr != noErr )
  208.     {
  209.         fSuspended     = false;
  210.         return tErr;
  211.     }
  212.     else
  213.     {
  214.         fSuspended     = true;
  215.     }
  216.     
  217.         //————    Duplicate the AppeEvent Record, and reset the pointers
  218.     fMessage     = *fMessagePtr;
  219.     fMessagePtr    = &fMessage;
  220.  
  221.     fReply        = *fReplyPtr;
  222.     fReplyPtr     = &fReply;
  223.     
  224.  
  225.         //————    Get the return ID of the AppleEvent
  226.     tErr = SetupReturnID();
  227.     if( tErr != noErr )
  228.     {
  229.         SetErrorCode( tErr );
  230.         SetErrorMessage( "Failed to extract return id from AppleEvent." );
  231.         return tErr;
  232.     }
  233.  
  234.         //————    Get the Service Indentifier from the AppleEvent
  235.         //————    This string identifies which service is requested
  236.     tErr = SetupSeviceIdentifier();
  237.     if( tErr != noErr )
  238.     {
  239.         SetErrorCode( tErr );
  240.         SetErrorMessage( "Failed to extract service identifier." );
  241.         return tErr;
  242.     }
  243.  
  244.         //————    Get the service parameters from the AppleEvent
  245.         //————    and install them into this Request.
  246.     tErr = SetupParameterList();
  247.     if( tErr != noErr )
  248.     {
  249.         SetErrorCode( tErr );
  250.         SetErrorMessage( "Failed to extract parameters." );
  251.         return tErr;
  252.     }
  253.  
  254.         //————    Get the service parameters from the AppleEvent
  255.         //————    and install them into this Request.
  256.     tErr = SetupRequestIdentifier();
  257.     if( tErr != noErr )
  258.     {
  259.         SetErrorCode( tErr );
  260.         SetErrorMessage( "Failed to extract return ID." );
  261.         return tErr;
  262.     }
  263.     
  264.         //————    Call Parent class's Initialize
  265.     tErr = Request::Initialize();
  266.     if( tErr )
  267.     {
  268.         return tErr;
  269.     }
  270.     
  271.     return noErr;
  272. }
  273.  
  274. //—————————————————————————————————————————————————————————————————————————————————————
  275. //    AERequest::SetupReturnID    -    Get the AppleEvent's return ID
  276. //—————————————————————————————————————————————————————————————————————————————————————
  277. OSErr
  278. AERequest::SetupReturnID()
  279. {
  280.     OSErr        tErr;
  281.     long        tResult;
  282.     DescType    tActualType;
  283.     Size        tActualSize;
  284.     
  285.     tErr = AEGetAttributePtr(    fMessagePtr,
  286.                                 keyReturnIDAttr,
  287.                                 typeLongInteger,
  288.                                 &tActualType,
  289.                                 (Ptr)&tResult,
  290.                                 sizeof( tResult ),
  291.                                 &tActualSize );
  292.     if( tErr == noErr )
  293.     {
  294.         fReturnID = tResult;
  295.     }
  296.     else
  297.     {
  298.         fReturnID = 0;
  299.     }
  300.     return tErr;
  301. }
  302.  
  303. //—————————————————————————————————————————————————————————————————————————————————————
  304. //    AERequest::SetupSeviceIdentifier    -    Get the AppleEvent's direct parameter
  305. //                                It contains the text which identifies
  306. //                                which service is requested
  307. //—————————————————————————————————————————————————————————————————————————————————————
  308. OSErr
  309. AERequest::SetupSeviceIdentifier()
  310. {
  311.     OSErr        tErr;
  312.     char        tText[256];
  313.     DescType    tActualType;
  314.     Size        tActualSize;
  315.     
  316.     tErr = AEGetParamPtr(    fMessagePtr,
  317.                             kVUAESrvcName,
  318.                             typeChar,
  319.                             &tActualType,
  320.                             (Ptr)tText,
  321.                             255,
  322.                             &tActualSize );
  323.     if( tErr == noErr )
  324.     {
  325.         tText[tActualSize] = '\0';    //————    Terminate C string with null character
  326.         SetWhichService( tText );
  327.     }
  328.     else
  329.     {
  330.         SetWhichService( nil );
  331.     }
  332.     return tErr;
  333. }
  334.  
  335. //—————————————————————————————————————————————————————————————————————————————————————
  336. //    AERequest::SetupParameterList    -    Get the AppleEvent's 'extp' parameter
  337. //                                It contains the list of parameters for the Service
  338. //—————————————————————————————————————————————————————————————————————————————————————
  339. OSErr
  340. AERequest::SetupParameterList()
  341. {
  342.     OSErr            tErr;
  343.     AEDescList        tParamDesc;
  344.     VUList*            tParamValue;
  345.     
  346.     tErr = AEGetParamDesc(    fMessagePtr,
  347.                             kVUAESrvcParameters,
  348.                             typeAEList,
  349.                             &tParamDesc );
  350.     if( tErr != noErr )
  351.     {
  352.             //————    Some services may have no parameters, 
  353.             //————    so allow errAEDescNotFound error
  354.         if( tErr == errAEDescNotFound )
  355.         {
  356.             return noErr;
  357.         }
  358.         else
  359.         {
  360.             return tErr;
  361.         }
  362.     }
  363.     else
  364.     {
  365.         tErr = MakeVUListFromDescList( &tParamDesc, &tParamValue );
  366.         if( tParamValue != nil )
  367.         {
  368.             SetParameterList( tParamValue );
  369.         }
  370.         AEDisposeDesc( &tParamDesc );
  371.     }
  372.     return tErr;
  373. }
  374.  
  375. //—————————————————————————————————————————————————————————————————————————————————————
  376. //    AERequest::SetupRequestIdentifier    -    Get the AppleEvent's return ID
  377. //—————————————————————————————————————————————————————————————————————————————————————
  378. OSErr
  379. AERequest::SetupRequestIdentifier()
  380. {
  381.     OSErr            tErr;
  382.     long            tReturnID;
  383.     DescType        tActualType;
  384.     Size            tActualSize;
  385.     
  386.     tErr = AEGetAttributePtr(    fMessagePtr,
  387.                                 keyReturnIDAttr,
  388.                                 typeLongInteger,
  389.                                 &tActualType,
  390.                                 (Ptr)&tReturnID,
  391.                                 sizeof( long ),
  392.                                 &tActualSize );
  393.     if( tErr == noErr )
  394.     {
  395.             //————    Set the Request Identifier
  396.         SetRequestIdentifier( tReturnID );
  397.     }
  398.     else
  399.     {
  400.             //————    Set the Request Identifier to zero
  401.         SetRequestIdentifier( 0 );
  402.     }
  403.     return tErr;
  404. }
  405.  
  406. //—————————————————————————————————————————————————————————————————————————————————————
  407. //    AERequest::MakeVUListFromDescList    -    Convert the AEDescList 
  408. //                                                    to a VUList object.
  409. //—————————————————————————————————————————————————————————————————————————————————————
  410. OSErr
  411. AERequest::MakeVUListFromDescList( AEDescList* pDescList, VUList** pValue )
  412. {
  413.     OSErr            tErr;
  414.     long            tParamCount;
  415.     long            i;
  416.     AEKeyword        tActualKey;
  417.     DescType        tActualType;
  418.     Size            tActualSize;
  419.     short            tShort;
  420.     long            tLong;
  421.     Boolean            tBoolean;
  422.     char*            tText;
  423.     AEDescList        tDescList;
  424.     VUList*            tReturnVUList;
  425.     VUList*            tVUList;
  426.     
  427.     
  428.         //————    Construct the VUList object to eventually return
  429.     tReturnVUList = new VUList();
  430.     if( tReturnVUList == nil )
  431.     {
  432.         pValue = nil;
  433.         return memFullErr;
  434.     }
  435.  
  436.         //————    Get the number of Descriptors in the list
  437.     tErr = AECountItems( pDescList, &tParamCount );
  438.     if( tErr )
  439.     {
  440.         pValue = nil;
  441.         return tErr;
  442.     }
  443.  
  444.         //————    For each Descriptor in the list
  445.     for( i = 1; i <= tParamCount; i++ )
  446.     {
  447.             //————    Determine the type of the ith Descriptor
  448.         tErr = AESizeOfNthItem( pDescList, i, &tActualType, &tActualSize );
  449.         if( tErr )
  450.         {
  451.             break;
  452.         }
  453.         
  454.             //————    Depending on the type,
  455.             //————    Extract the data and put it into ScriptValue
  456.         switch( tActualType )
  457.         {
  458.                 //————————————————————————————————————————————————————
  459.                 //————    typeBoolean, typeFalse, typeTrue
  460.             case typeBoolean:
  461.             case typeTrue:
  462.             case typeFalse:
  463.             {                
  464.                     //————    typeBoolean 
  465.                 if( tActualType == typeBoolean )
  466.                 {
  467.                     tErr = AEGetNthPtr(    pDescList,
  468.                                         i,
  469.                                         tActualType,
  470.                                         &tActualKey,
  471.                                         &tActualType,
  472.                                         (Ptr)&tBoolean,
  473.                                         sizeof(Boolean),
  474.                                         &tActualSize );
  475.                     if( tErr == noErr )
  476.                     {
  477.                         tReturnVUList->PutNthItem( tBoolean );     //————    defaults to appending
  478.                     }
  479.                 }
  480.                 else
  481.                 {
  482.                         //————    typeFalse & typeFalse
  483.                     tReturnVUList->PutNthItem( (Boolean)(tActualType == typeTrue) );     //————    defaults to appending
  484.                 }
  485.             }
  486.             break;
  487.  
  488.                 //————————————————————————————————————————————————————
  489.                 //————    typeShortInteger
  490.             case typeShortInteger:
  491.             {
  492.                 tErr = AEGetNthPtr(    pDescList,
  493.                                     i,
  494.                                     typeShortInteger,
  495.                                     &tActualKey,
  496.                                     &tActualType,
  497.                                     (Ptr)&tShort,
  498.                                     sizeof(short),
  499.                                     &tActualSize );
  500.                 if( tErr == noErr )
  501.                 {
  502.                     tReturnVUList->PutNthItem( tShort ); //————    defaults to appending
  503.                 }
  504.             }
  505.             break;
  506.  
  507.                 //————————————————————————————————————————————————————
  508.                 //————    typeLongInteger
  509.             case typeLongInteger:
  510.             {
  511.                 tErr = AEGetNthPtr(    pDescList,
  512.                                     i,
  513.                                     typeLongInteger,
  514.                                     &tActualKey,
  515.                                     &tActualType,
  516.                                     (Ptr)&tLong,
  517.                                     sizeof(long),
  518.                                     &tActualSize );
  519.                 if( tErr == noErr )
  520.                 {
  521.                     tReturnVUList->PutNthItem( tLong ); //————    defaults to appending
  522.                 }
  523.             }
  524.             break;
  525.  
  526.                 //————————————————————————————————————————————————————
  527.                 //————    typeChar
  528.             case typeChar:
  529.             {
  530.                 tText = new char[ tActualSize + 1 ];
  531.                 if( tText )
  532.                 {
  533.                     tErr = AEGetNthPtr(    pDescList,
  534.                                         i,
  535.                                         typeChar,
  536.                                         &tActualKey,
  537.                                         &tActualType,
  538.                                         (Ptr)tText,
  539.                                         tActualSize + 1,
  540.                                         &tActualSize );
  541.                     if( tErr == noErr )
  542.                     {
  543.                         tText[tActualSize] = '\0';
  544.                         tReturnVUList->PutNthItem( tText ); //————    defaults to appending
  545.                     }
  546.                     delete tText;
  547.                 }
  548.             }
  549.             break;
  550.  
  551.                 //————————————————————————————————————————————————————
  552.                 //————    typeAEList
  553.                 //————    We have to make a recursive call to this same method
  554.                 //————    in order to accomplish translation of an AEDescList
  555.             case typeAEList:
  556.             {
  557.                     //————    Extract the AEDescList
  558.                 tErr = AEGetNthDesc(    pDescList,
  559.                                         i,
  560.                                         typeAEList,
  561.                                         &tActualKey,
  562.                                         &tDescList );
  563.                 if( tErr == noErr )
  564.                 {
  565.                         //————    Now convert the DescList into a VUList
  566.                     tErr = MakeVUListFromDescList( &tDescList, &tVUList );
  567.                     if( tErr == noErr )
  568.                     {
  569.                         if( tVUList != nil )
  570.                         {
  571.                             tReturnVUList->PutNthItem( tVUList ); //————    defaults to appending
  572.                         }
  573.                     }
  574.                     AEDisposeDesc( &tDescList );
  575.                 }
  576.             }
  577.             break;
  578.  
  579.                 //————————————————————————————————————————————————————
  580.                 //————    default case, unknown data type in AEDesc
  581.                 //————    use VUNull to represent an 'undefined'
  582.                 //————    It also forms a place holder so list
  583.                 //————    elements retail their order, and errors are 
  584.                 //————    isolated with less grief
  585.             default:
  586.             {
  587.                 tReturnVUList->PutNthItem( new VUNull() );
  588.             }
  589.             break;
  590.  
  591.         }
  592.         
  593.             //————    Break out of FOR loop if an error was encountered
  594.         if( tErr != noErr )
  595.         {
  596.             break;
  597.         }
  598.     }
  599.     *pValue = tReturnVUList;
  600.     return tErr;
  601. }
  602.  
  603. //—————————————————————————————————————————————————————————————————————————————————————
  604. //    AERequest::ResetTimeOutCounter    - inform V.U. to not let this AppleEvent
  605. //        time out for the indicated number of seconds
  606. //—————————————————————————————————————————————————————————————————————————————————————
  607. void
  608. AERequest::ResetTimeOutCounter( unsigned long pNewTimeOutInterval )
  609. {
  610.     const    unsigned long     kResetSendThreshold    =    600;
  611.     
  612.     if( !HasBeenCanceled() )
  613.     {
  614.         if( fSendResetTicks - TickCount() < kResetSendThreshold )
  615.         {
  616.                 //————    Send message to V.U. to reset the time out counter
  617.             SendTimeOutResetMessage( pNewTimeOutInterval );
  618.  
  619.                 //————    Call Parent class method
  620.             Request::ResetTimeOutCounter( pNewTimeOutInterval );
  621.         }
  622.     }
  623. }
  624.  
  625. //—————————————————————————————————————————————————————————————————————————————————————
  626. //    AERequest::SendTimeOutResetMessage - Send an AppleEvent to V.U. to
  627. //        reset the Time Out counter for this AppleEvent
  628. //—————————————————————————————————————————————————————————————————————————————————————
  629. OSErr
  630. AERequest::SendTimeOutResetMessage( unsigned long pNewTimeOutInterval )
  631. {
  632.     OSErr            tErr;
  633.     AEAddressDesc    tAddressDesc;
  634.     AppleEvent        tDummyReply;
  635.  
  636.         //————    If we have not already built an event for reseting the timer, do so now
  637.     if( !fHaveResetTimerMsg )
  638.     {
  639.             //————    Get the Target Address Descriptor from the existing default reply AppleEvent
  640.         tErr = AEGetAttributeDesc(    fReplyPtr,
  641.                                     keyAddressAttr,
  642.                                     typeWildCard,
  643.                                     &tAddressDesc );
  644.         if( tErr )
  645.         {
  646.                 //————    not much further we can do, except return the error code
  647.             return tErr;
  648.         }
  649.     
  650.         
  651.             //————    Construct the AppleEvent for sending to V.U.
  652.         tErr = AECreateAppleEvent(    kVUAETool,
  653.                                     kVUAEWaitLonger,
  654.                                     &tAddressDesc,
  655.                                     kAutoGenerateReturnID,
  656.                                     kAnyTransactionID,
  657.                                     &fResetTimerMsg );
  658.             //————    We no longer need the Address descriptor
  659.         AEDisposeDesc( &tAddressDesc );
  660.         if( tErr )
  661.         {
  662.                 //————    not much further we can do, except return the error code
  663.             return tErr;
  664.         }
  665.         
  666.             //————    Put the same return ID as the original AppleEvent from V.U.
  667.             //————    V.U. uses the return ID to determine which AppleEvent needs its timer reset
  668.         tErr = AEPutAttributePtr(    &fResetTimerMsg,
  669.                                        keyReturnIDAttr,
  670.                                        typeLongInteger,
  671.                                        (Ptr)&fReturnID,
  672.                                       sizeof( long ) );
  673.         
  674.             //————    We now have an AppleEvent that we can send, and we need to dispose of later
  675.         fHaveResetTimerMsg = true;
  676.     }
  677.     
  678.         //————    Put the amount of time required to complete the current service request
  679.         //————    into the AppleEvent
  680.     tErr = AEPutParamPtr(    &fResetTimerMsg,
  681.                                kVUAEWaitAmount,
  682.                                typeMagnitude,
  683.                                (Ptr)&pNewTimeOutInterval,
  684.                               sizeof( pNewTimeOutInterval ) );
  685.     if( tErr )
  686.     {
  687.             //————    not much further we can do, except return the error code
  688.         return tErr;
  689.     }
  690.     
  691.     
  692.     tErr = AESend(    &fResetTimerMsg,
  693.                     &tDummyReply,
  694.                     kAENoReply + kAENeverInteract,
  695.                     kAEHighPriority,
  696.                     kAEDefaultTimeout,
  697.                     nil,
  698.                     nil );
  699.     if( tErr )
  700.     {
  701.             //————    not much further we can do, except return the error code
  702.         return tErr;
  703.     }
  704.  
  705.     return noErr;
  706. }
  707.  
  708. //—————————————————————————————————————————————————————————————————————————————————————
  709. //    AERequest::SendResult    - send the result back to VU
  710. //—————————————————————————————————————————————————————————————————————————————————————
  711. void
  712. AERequest::SendResult()
  713. {
  714.     OSErr        tErr;
  715.     
  716.         //————    If a return value exists, install it in the reply event
  717.     if( fReturnValue != nil )
  718.     {
  719.         tErr = PutReturnValueIntoReplyEvent();
  720.     }    
  721.     
  722.         //————    Resume the processing of this AppleEvent pair
  723.         //————    This causes the reply event to be sent back to V.U.
  724.     tErr = AEResumeTheCurrentEvent(    fMessagePtr,
  725.                                        fReplyPtr,
  726.                                     (EventHandlerProcPtr)kAENoDispatch,
  727.                                     0 );
  728.  
  729.     if( tErr == noErr )
  730.     {
  731.         fSuspended     = false;
  732.     }
  733. }
  734.  
  735. //—————————————————————————————————————————————————————————————————————————————————————
  736. //    AERequest::PutReturnValueIntoReplyEvent    -    Convert the ScriptValue 
  737. //                                                        to an AE Descriptor.
  738. //—————————————————————————————————————————————————————————————————————————————————————
  739. OSErr
  740. AERequest::PutReturnValueIntoReplyEvent()
  741. {
  742.     OSErr            tErr;
  743.     Boolean            tBoolean;
  744.     short            tShort;
  745.     long            tLong;
  746.     char*            tText;
  747.     unsigned short    tTextSize;
  748.     AEDescList        tDescList;
  749.         
  750.         //————    Put the value into the reply event according to its kind
  751.     switch( fReturnValue->GetValueKind() )
  752.     {
  753.         case kVUBooleanKind:
  754.         {
  755.             tBoolean = ((VUBoolean*)fReturnValue)->GetBoolean();
  756.             if( tBoolean )
  757.             {
  758.                 tErr = AEPutParamPtr(    fReplyPtr,
  759.                                         kVUAESrvcResults,
  760.                                         typeTrue,
  761.                                         (Ptr)&tBoolean,
  762.                                         sizeof(Boolean) );
  763.             }
  764.             else
  765.             {
  766.                 tErr = AEPutParamPtr(    fReplyPtr,
  767.                                         kVUAESrvcResults,
  768.                                         typeFalse,
  769.                                         (Ptr)&tBoolean,
  770.                                         sizeof(Boolean) );
  771.             }
  772.             if( tErr )
  773.             {
  774.                 SetErrorCode( tErr );
  775.                 SetErrorMessage( "Failed to install return value into the reply." );
  776.             }
  777.         }
  778.         break;
  779.         
  780.         case kVUNumberKind:
  781.         {
  782.             tShort = ((VUNumber*)fReturnValue)->GetNumber();
  783.             tErr = AEPutParamPtr(    fReplyPtr,
  784.                                        kVUAESrvcResults,
  785.                                        typeShortInteger,
  786.                                        (Ptr)&tShort,
  787.                                        sizeof(short) );
  788.             if( tErr )
  789.             {
  790.                 SetErrorCode( tErr );
  791.                 SetErrorMessage( "Failed to install return value into the reply." );
  792.             }
  793.         }
  794.         break;
  795.         
  796.         case kVULongNumberKind:
  797.         {
  798.             tLong = ((VULongNumber*)fReturnValue)->GetNumber();
  799.             tErr = AEPutParamPtr(    fReplyPtr,
  800.                                        kVUAESrvcResults,
  801.                                        typeLongInteger,
  802.                                        (Ptr)&tLong,
  803.                                        sizeof(long) );
  804.             if( tErr )
  805.             {
  806.                 SetErrorCode( tErr );
  807.                 SetErrorMessage( "Failed to install return value into the reply." );
  808.             }
  809.         }
  810.         break;
  811.         
  812.         case kVUStringKind:
  813.         {
  814.             tText = ((VUString*)fReturnValue)->GetText();
  815.             if( tText != nil )
  816.             {
  817.                 if( (tTextSize = strlen( tText )) > 0)
  818.                 {
  819.                     tErr = AEPutParamPtr(    fReplyPtr,
  820.                                             kVUAESrvcResults,
  821.                                             typeChar,
  822.                                             (Ptr)tText,
  823.                                             tTextSize );
  824.                     if( tErr )
  825.                     {
  826.                         SetErrorCode( tErr );
  827.                         SetErrorMessage( "Failed to install return value into the reply." );
  828.                     }
  829.                 }
  830.             }
  831.         }
  832.         break;
  833.         
  834.         case kVUListKind:
  835.         {
  836.             tErr = MakeDescListFromVUList( (VUList*)fReturnValue, &tDescList );
  837.             if( tErr == noErr )
  838.             {
  839.                 tErr = AEPutParamDesc(    fReplyPtr,
  840.                                         kVUAESrvcResults,
  841.                                         &tDescList );
  842.                 AEDisposeDesc( &tDescList );
  843.             }
  844.         }
  845.         break;
  846.  
  847.         default:
  848.         {
  849.         
  850.         }
  851.         break;
  852.     }
  853.  
  854.  
  855.     return tErr;
  856. }
  857.  
  858. //—————————————————————————————————————————————————————————————————————————————————————
  859. //    AERequest::MakeDescListFromVUList    -    Convert the VUList 
  860. //                                                    to a pDescList object.
  861. //—————————————————————————————————————————————————————————————————————————————————————
  862. OSErr
  863. AERequest::MakeDescListFromVUList( VUList* pValue, AEDescList* pDescList )
  864. {
  865.     OSErr            tErr;
  866.     short            tItemCount;
  867.     short            i;
  868.     ScriptValue*    tVal;
  869.     Boolean            tBoolean;
  870.     short            tShort;
  871.     long            tLong;
  872.     char*            tText;
  873.     AEDescList        tDescList;
  874.     ValueKind        tValueKind;
  875.     
  876.         //————    Create the AEDescList to fill with the values in the VUList
  877.     tErr = AECreateList( nil, 0, false, pDescList );
  878.     if( tErr )
  879.     {
  880.         return tErr;
  881.     }
  882.         //————    Get the number of items in the VUList
  883.     tItemCount = pValue->GetCount();
  884.     
  885.         //————    Put each item of the VUList, into the AEDescList
  886.     for( i = 1; i <= tItemCount; i++ )
  887.     {
  888.             //————    Get the ith ScriptValue object from the VUList
  889.         tValueKind = kVUAnyKind;
  890.         tErr = pValue->GetNthItem( i, tVal, tValueKind );
  891.         if( tVal )
  892.         {
  893.                 //————    if we got one, process it according to its kind
  894.             switch( tValueKind )
  895.             {
  896.  
  897.                     //————    VUBoolean object
  898.                 case kVUBooleanKind:
  899.                 {
  900.                     tBoolean = ((VUBoolean*)tVal)->GetBoolean();
  901.                     tErr = AEPutPtr(    pDescList,
  902.                                           i,
  903.                                           typeBoolean,
  904.                                           (Ptr)&tBoolean,
  905.                                           sizeof(Boolean) );
  906.                 }
  907.                 break;
  908.  
  909.                     //————    VUNumber object
  910.                 case kVUNumberKind:
  911.                 {
  912.                     tShort = ((VUNumber*)tVal)->GetNumber();
  913.                     tErr = AEPutPtr(    pDescList,
  914.                                           i,
  915.                                           typeShortInteger,
  916.                                           (Ptr)&tShort,
  917.                                           sizeof(short) );
  918.                 }
  919.                 break;
  920.  
  921.                     //————    VULongNumber object
  922.                 case kVULongNumberKind:
  923.                 {
  924.                     tLong = ((VULongNumber*)tVal)->GetNumber();
  925.                     tErr = AEPutPtr(    pDescList,
  926.                                           i,
  927.                                           typeLongInteger,
  928.                                           (Ptr)&tLong,
  929.                                           sizeof(long) );
  930.                 }
  931.                 break;
  932.  
  933.                     //————    VUString object
  934.                 case kVUStringKind:
  935.                 {
  936.                     tText = ((VUString*)tVal)->GetText();
  937.                     if( tText )
  938.                     {
  939.                         tErr = AEPutPtr(    pDescList,
  940.                                             i,
  941.                                             typeChar,
  942.                                             (Ptr)tText,
  943.                                             strlen(tText) );
  944.                     }
  945.                 }
  946.                 break;
  947.  
  948.                     //————    VUList object
  949.                 case kVUListKind:
  950.                 {
  951.                     tErr = MakeDescListFromVUList( (VUList*)tVal, &tDescList );
  952.                     if( tErr == noErr )
  953.                     {
  954.                         tErr = AEPutDesc(    pDescList,
  955.                                             i,
  956.                                             &tDescList );
  957.                         AEDisposeDesc( &tDescList );
  958.                     }
  959.                 }
  960.                 break;
  961.  
  962.                 default:
  963.                 {
  964.                 }
  965.                 break;
  966.             }
  967.                 //————    Break out of for loop, if there was an error
  968.             if( tErr )
  969.             {
  970.                 break;
  971.             }
  972.         }
  973.     }
  974.  
  975.         //————    if there was an error, dispose of the AEDescList created earlier
  976.     if( tErr )
  977.     {
  978.         AEDisposeDesc( &tDescList );
  979.     }
  980.     return tErr;
  981. }
  982.  
  983.